﻿using System;
using System.Collections.Concurrent;

namespace ESoft.Pool
{
    /// <summary>
    /// 通用对象池
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ObjectPool<T> : IObjectPool<T>
    {
        /// <summary>
        /// 对象池
        /// </summary>
        protected ConcurrentBag<T> Objects { get; }

        /// <summary>
        /// 
        /// </summary>
        protected Func<T> ObjectGenerator { get; }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="objectGenerator"></param>
        public ObjectPool(Func<T> objectGenerator)
        {
            ObjectGenerator = objectGenerator ?? throw new ArgumentNullException(nameof(objectGenerator));
            Objects = new ConcurrentBag<T>();
        }

        /// <summary>
        /// 取出对象
        /// </summary>
        /// <returns></returns>
        public T Get() => Objects.TryTake(out T item) ? item : ObjectGenerator();

        /// <summary>
        /// 归还对象
        /// </summary>
        /// <param name="item"></param>
        public void Return(T item) => Objects.Add(item);
    }

}
